using System;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Text;
using System.Windows.Forms;
using Microsoft.Practices.EnterpriseLibrary.Data;

using Syncfusion.Windows.Forms.Grid;
using ctsu.BaseForms;
using ctsu.Data;
using ctsu.Admin.Forms;

namespace ctsu.Admin.BusLogic.CoreLab
{
	class BLCoreLabFormGridSstChangeLocation : BLCoreLabFormGridBaseImpl
	{
		private Button _btnUpdateSelected;
		private Button _btnUpdateAll;

		public BLCoreLabFormGridSstChangeLocation(FormGridMeta formGridMeta, GridControl grid, FormInfoBase formInfo, Form form)
			: base(formGridMeta, grid, formInfo, form)
		{
		}

		#region initialize
		public override bool Initialize()
		{
			_btnUpdateSelected = (Button)Forms.Utils.GetControlByName("btnUpdateSelected", this._form.Controls);
			_btnUpdateAll = (Button)Forms.Utils.GetControlByName("btnUpdateAll", this._form.Controls);
			_errorControl = (Label)Forms.Utils.GetControlByName("errCtl", this._form.Controls);
			_btnRemoveBatch = (Button)Forms.Utils.GetControlByName("btnRemoveBatch", this._form.Controls);
			_btnPrint = (Button)Forms.Utils.GetControlByName("btnPrint", this._form.Controls);
			_btnSave = (Button)Forms.Utils.GetControlByName("btnSave", this._form.Controls);

			StringBuilder sb = new StringBuilder();
			string sql = "SELECT s.ID, s.PatientName, s.Protocol, " +
				" st.Display, s.Location, s.OutDate, s.Disposition, s.Notes, s.BatchNum " +
				" FROM Sst s LEFT JOIN SampleType_L st" +
				" ON s.SampleType = st.ID " +
				" WHERE 1=2 ";

			try
			{
				this._tableSchema = Forms.Utils.GetTableSchema(null, sql);
				InitializeGridControl();
				/*this is where change loacation differs from check-in
				 _data (table) is initialized here */
				InitializeTable();
				return true;
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve grid table schema!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Grid Data Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
		}

		private void InitializeGridControl()
		{
			this._grid.BeginUpdate();
			//this adds up the total column width
			int totColWidth = 0;

			int col = 1;
			//create the new grid columns for drawSamples			
			this._grid.ColCount = this._formGridMeta.GridColumns.Count;
			//start with drawSamples table
			foreach (DataColumn dc in this._tableSchema.Columns)
			{
				//get the metadata for this column
				if (!this._formGridMeta.GridColumns.Contains(dc.ColumnName))
					continue;

				FormGridColumnMeta fgcm = (FormGridColumnMeta)this._formGridMeta.GridColumns[dc.ColumnName];
				//store the dataColum in the tag property
				//in the header row
				this._grid[0, col].Tag = dc;
				this._grid[0, col].Text = fgcm.DisplayName;
				GridStyleInfo gsi = this._grid.ColStyles[col];
				gsi.CellType = fgcm.CellType;
				gsi.Enabled = true;

				if (fgcm.CellType == "CheckBox")
				{
					gsi.CheckBoxOptions = new GridCheckBoxCellInfo("1", "0", "", true);
					gsi.TriState = false;
					gsi.CellValueType = typeof(string);
					gsi.CellValue = "0";

				}
				else
				{
					gsi.CellValue = null;
					gsi.CellValueType = Type.GetType(fgcm.DataType);

					if (fgcm.CellType == "ComboBox")
					{
						BindGridColumn(fgcm, gsi);
						gsi.DropDownStyle = GridDropDownStyle.AutoComplete;
						gsi.ReadOnly = false;
					}
				}

				this._grid.ColWidths[col] = fgcm.Width;
				totColWidth += fgcm.Width;
				if (fgcm.IsHidden)
					this._grid.Cols.Hidden[col] = true;
				if (fgcm.ReadOnly)
					gsi.ReadOnly = true;
				col++;
			}

			HookGridEvents();

			//			if(totColWidth < MaxWidth)
			//				this._grid.Width = totColWidth + 60;

			this._grid.ResizeRowsBehavior = GridResizeCellsBehavior.None;
			this._grid.Model.RowHeights.ResizeToFit(GridRangeInfo.Row(0), GridResizeToFitOptions.IncludeHeaders);
			this._grid.EndUpdate();
		}
		private void InitializeTable()
		{
			string sql = "SELECT s.ID, s.PatientName, s.Protocol, " +
				" st.Display, s.Location, s.OutDate, s.Disposition, s.Notes, s.BatchNum " +
				" FROM Sst s LEFT JOIN SampleType_L st" +
				" ON s.SampleType = st.ID " +
				" WHERE 1=2 ";

			//SqlConnection conn = LoginForm.GetSqlConnection();			
			StringBuilder sb = new StringBuilder();
			try
			{
				DataSet ds = DataAccess.GetDataSet(sql);
				_data = ds.Tables[0];
				this._grid.RowCount = 0;
			}
			catch (Exception ex)
			{
				sb.Append("Could not initialize grid table!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Initialize Grid Table Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
		}
		#endregion initialize

		public override void New()
		{
			InitializeTable();
		}

		#region get display data
		public override void SetEnabled(bool enable)
		{
			GridStyleInfo gsi = null;
			FormGridColumnMeta fgcm = null;

			this._grid.IgnoreReadOnly = true;
			if (enable)
			{
				if (this._grid.RowCount > 0)
				{

					this._btnRemoveBatch.Enabled = true;
					this._btnUpdateAll.Enabled = true;
					this._btnUpdateSelected.Enabled = true;
				}
				//enable non-readonly cols
				for (int i = 1; i <= this._grid.ColCount; i++)
				{
					fgcm = (FormGridColumnMeta)this._formGridMeta.GridColumnsOrdered[i - 1];
					gsi = this._grid.ColStyles[i];
					if (!fgcm.ReadOnly)
						gsi.ReadOnly = false;
				}
			}
			else
			{
				//disable non-readonly cols				
				for (int i = 1; i <= this._grid.ColCount; i++)
				{
					fgcm = (FormGridColumnMeta)this._formGridMeta.GridColumnsOrdered[i - 1];
					gsi = this._grid.ColStyles[i];
					if (!fgcm.ReadOnly)
						gsi.ReadOnly = true;
				}
			}
			this._grid.IgnoreReadOnly = false;
		}

		public override bool GetData(int id)
		{
			StringBuilder sb = new StringBuilder();
			//first get the label ids for this batch id
			string sql = "SELECT SstID From SstEditBatchSamples " +
				" WHERE BatchID =" + id +
				" ORDER BY SstID";

			//SqlConnection conn = LoginForm.GetSqlConnection();			
			IDataReader reader = null;

			DataSet ds = new DataSet();
			try
			{
				//conn.Open();
				reader = DataAccess.GetDataReader(sql);


				//				DataRow dr;
				//				while(reader.Read())
				//				{
				//					dr = GetDataRow(reader.GetInt32(0));
				//					this._data.Rows.Add(dr);
				//				}
				//				_data.AcceptChanges();

				while (reader.Read())
				{
					MergeDs(reader.GetInt32(0), ds);
				}

				reader.Close();
				_data = ds.Tables[0];
				this._grid.BeginUpdate();
				this._grid.RowCount = 0;

				this._grid.RowCount = _data.Rows.Count;
				int row = 1;
				foreach (DataRow dr2 in _data.Rows)
				{
					//store the dataRow in the cell.tag of the header column
					this._grid[row, 0].Tag = dr2;
					DisplayRow(row, dr2);
					row++;
				}
				this._grid.EndUpdate();
				if (this._grid.RowCount > 0)
					this._btnPrint.Enabled = true;
				else
					this._btnPrint.Enabled = false;

			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message);
				//TODO - need to do more here for exception				
				MessageBox.Show("GetGridData Exception");
				return false;
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
			return true;

		}

		private void MergeDs(int id, DataSet ds1)
		{
			string sql = "SELECT s.ID, s.PatientName, s.Protocol, " +
				" st.Display, s.Location, s.OutDate, s.Disposition, s.Notes, s.BatchNum " +
				" FROM Sst s LEFT JOIN SampleType_L st" +
				" ON s.SampleType = st.ID " +
				" WHERE s.ID =" + id;

			//SqlConnection conn = LoginForm.GetSqlConnection();			
			StringBuilder sb = new StringBuilder();
			try
			{
				DataSet ds = DataAccess.GetDataSet(sql);
				if (ds.Tables.Count > 0)
				{
					ds1.Merge(ds);
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not GetDataRow for grid!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "GetDataRow Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
		}

		private DataRow GetDataRow(int id)
		{
			string sql = "SELECT s.ID, s.PatientName, s.Protocol, " +
				" st.Display, s.Location, s.OutDate, s.Disposition, s.Notes, s.BatchNum " +
				" FROM Sst s LEFT JOIN SampleType_L st" +
				" ON s.SampleType = st.ID " +
				" WHERE s.ID =" + id;

			//SqlConnection conn = LoginForm.GetSqlConnection();			
			StringBuilder sb = new StringBuilder();
			try
			{
				DataSet ds = DataAccess.GetDataSet(sql);
				if (ds.Tables.Count > 0)
				{
					if (ds.Tables[0].Rows.Count > 0)
						return ds.Tables[0].Rows[0];
				}
				return null;
			}
			catch (Exception ex)
			{
				sb.Append("Could not GetDataRow for grid!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "GetDataRow Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return null;
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
		}

		protected override void DisplayRow(int row, DataRow dr)
		{
			string message = "";
			for (int i = 1; i < this._grid.ColCount + 1; i++)
			{
				DataColumn dc = (DataColumn)this._grid[0, i].Tag;

				if (this._grid[row, i].CellType == "CheckBox")
				{
					if (dr[dc.ColumnName] != System.DBNull.Value)
					{
						if ((bool)dr[dc.ColumnName])
							this._grid[row, i].CellValue = "1";
						else
							this._grid[row, i].CellValue = "0";
					}
				}
				else
					this._grid[row, i].CellValue = dr[dc.ColumnName];

				if (dc.ColumnName == "Protocol")
				{
					int protocol = Convert.ToInt32(dr[dc.ColumnName]);
					ProtocolInfo pi = CoreLabUtils.GetProtocolInfo(protocol, out message);
					this._grid[row, i].Tag = pi;
					if (pi.ID > -1)
						this._grid[row, i].CellTipText = pi.GetToolTip();
				}
				if (dc.ColumnName == "Patient")
				{
					int patient = Convert.ToInt32(dr[dc.ColumnName]);
					PatientInfo pi = CoreLabUtils.GetPatientInfo(patient, out message);
					this._grid[row, i].Tag = pi;
					if (pi.ID > -1)
						this._grid[row, i].CellTipText = pi.GetToolTip();
				}
			}
		}
		#endregion get display data

		#region add replace remove
		public override void ReplaceRow(object obj, int row)
		{
			this._grid.IgnoreReadOnly = true;
			DataRow dr = (DataRow)this._grid[row, 0].Tag;
			Sample samp = (Sample)obj;

			this._grid[row, 5].Text = samp.Location;
			AssignChangeToDataRow(row, 5);

			if (samp.OutDate.Ticks > 0)
			{
				this._grid[row, 6].CellValue = samp.OutDate;
				this._grid[row, 6].Format = "MM/dd/yyyy";
			}
			else
				this._grid[row, 6].Text = "";
			AssignChangeToDataRow(row, 6);

			//only if chkInclude
			if (samp.Disposition.Length > 0)
			{
				this._grid[row, 7].Text = samp.Disposition;
				AssignChangeToDataRow(row, 7);
			}
			if (samp.Note.Length > 0)
			{
				this._grid[row, 8].Text = samp.Note;
				AssignChangeToDataRow(row, 8);
			}
			this._btnSave.Enabled = true;
			this._grid.IgnoreReadOnly = false;
		}
		public override void AddRow(object obj, int row)
		{
			this._grid.IgnoreReadOnly = true;
			Sample samp = (Sample)obj;
			DataRow dr = _data.NewRow();
			this._data.Rows.Add(dr);

			int rows = ++this._grid.RowCount;

			this._grid[rows, 0].Tag = dr;

			this._grid[rows, 1].CellValue = samp.TestID;
			AssignChangeToDataRow(rows, 1);
			this._grid[rows, 2].CellValue = samp.PatientName;
			AssignChangeToDataRow(rows, 2);
			this._grid[rows, 3].CellValue = samp.Protocol;
			this._grid[rows, 3].Tag = samp.ProtocolInfo;
			this._grid[rows, 3].CellTipText = samp.ProtocolInfo.GetToolTip();
			AssignChangeToDataRow(rows, 3);
			this._grid[rows, 4].CellValue = samp.SampleName;
			AssignChangeToDataRow(rows, 4);
			this._grid[rows, 5].CellValue = samp.Location;
			AssignChangeToDataRow(rows, 5);
			if (samp.OutDate.Ticks > 0)
			{
				this._grid[rows, 6].CellValue = samp.OutDate;
				this._grid[rows, 6].Format = "MM/dd/yyyy";
			}
			else
				this._grid[rows, 6].Text = "";
			AssignChangeToDataRow(rows, 6);
			this._grid[rows, 7].Text = samp.Disposition;
			AssignChangeToDataRow(rows, 7);
			this._grid[rows, 8].Text = samp.Note;
			AssignChangeToDataRow(rows, 8);
			this._grid.IgnoreReadOnly = false;
			this._grid.ScrollCellInView(this._grid.RowCount, 0);
		}
		#endregion add replace remove

		#region save
		public override bool Save(int foreignID, out string message, Database db, DbTransaction trans)
		{
			message = "";
			if (_data == null)
				return true;
			int labelID;
			foreach (DataRow dr in _data.Rows)
			{
				labelID = (int)dr["ID"];
				if (dr.RowState == DataRowState.Added)
				{
					if (!InsertIntoBatch(labelID, foreignID, out message, db, trans))
						return false;
					if (!UpdateRow(dr, foreignID, out message, db, trans))
						return false;
				}
				else if (dr.RowState == DataRowState.Modified)
				{
					if (!UpdateRow(dr, foreignID, out message, db, trans))
						return false;
				}
			}
			return true;
		}

		private bool InsertIntoBatch(int sstID, int batchID, out string message, Database db, DbTransaction trans)
		{
			message = "";
			string sql = "INSERT INTO SstEditBatchSamples (BatchID,SstID) " +
				" VALUES(" + batchID + ", " + sstID + ")";

			try
			{
				DbCommand cmd = db.GetSqlStringCommand(sql);
				db.ExecuteNonQuery(cmd, trans);
				//SqlHelper.ExecuteNonQuery(trans, CommandType.Text, sql);				
			}
			catch (Exception ex)
			{
				message = ex.Message;
				return false;
			}
			return true;
		}

		private bool UpdateRow(DataRow dr, int foreignID, out string message, Database db, DbTransaction trans)
		{
			message = "";

			//sql update
			string sqlUpdate = "UPDATE Sst Set Location=@Location, Notes=@Notes, " +
				" Disposition=@Disposition, OutDate=@OutDate " +
				" WHERE ID=@ID";

			//sql parameters
			SqlParameter[] aParams = new SqlParameter[5];
			aParams[0] = new SqlParameter("@Location", SqlDbType.NVarChar, 50, "Location");
			aParams[1] = new SqlParameter("@Notes", SqlDbType.NVarChar, 4000, "Notes");
			aParams[2] = new SqlParameter("@Disposition", SqlDbType.NVarChar, 4000, "Disposition");
			aParams[3] = new SqlParameter("@ID", SqlDbType.Int, 0, "ID");
			aParams[4] = new SqlParameter("@OutDate", SqlDbType.DateTime, 0, "OutDate");
			//assign parameters
			AssignParameters(aParams, dr, foreignID, 0);

			try
			{
				DbCommand cmd = db.GetSqlStringCommand(sqlUpdate);
				DataAccess.AddParamArrayToDbCommand(cmd, aParams);

				int i = db.ExecuteNonQuery(cmd, trans);
				//SqlHelper.ExecuteNonQuery(trans, CommandType.Text, sqlUpdate, aParams);				
			}
			catch (Exception ex)
			{
				message = ex.Message;
				return false;
			}
			return true;
		}
		#endregion save
	}
}
